#include <iostream>
#include <fstream>

// 引入protobuf自动生成的通讯录数据结构定义头文件
#include "contacts.pb.h"

using namespace std;



//@brief 是 Doxygen 的标签，表示 “简要说明”。
//@param 是 Doxygen 的标签，表示 “函数参数说明”。

/**
 * @brief 打印通讯录中的所有联系人信息
 * @param contacts 常量引用，指向存储所有联系人数据的protobuf对象
 *                 使用const确保函数不会修改原始数据，提高安全性
 */
void PrintContacts(const contacts2::Contacts& contacts){
    // 遍历所有联系人，contacts_size()返回联系人总数
    for(int i = 0; i < contacts.contacts_size(); i++){
        cout << "--------------------联系人" << i+1 << "--------------------" << endl;
        // 通过contacts(i)获取第i个联系人的详细信息（protobuf生成的访问方法）
        const contacts2::PeopleInfo& people = contacts.contacts(i);
        
        // 打印联系人基本信息，调用protobuf生成的getter方法（name()、age()）
        cout << "联系人姓名：" << people.name() << endl;
        cout << "联系人年龄：" << people.age() << endl;
        
        // 遍历当前联系人的所有电话号码，phone_size()返回电话号码总数
        for(int j= 0; j < people.phone_size(); j++){
            // 通过phone(j)获取第j个电话号码对象
            const contacts2::PeopleInfo_Phone& phone = people.phone(j);
            cout << "联系人电话" << j+1 << "：" << phone.numbers();
            //希望格式 联系人电话1:12312312312 （MP）
            // phone.type()打印的格式是int类型也就是枚举的数字，用 phone.PhoneType_Name()将枚举的数字值转换为对应的名称字符串。
            cout << " (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        }
        if(people.has_data() && people.data().Is<contacts2::Address>()){
            contacts2::Address address;
            people.data().UnpackTo(&address);//返回值是bool类型
            if(!address.home_address().empty()){
                cout << "联系人家庭住址：" << address.home_address() << endl;
            }
            if(!address.unit_address().empty()){
                cout << "联系人单位住址：" << address.unit_address() << endl;
            }
        }
        // if(people.has_qq()){
        //     cout << "联系人QQ号：" << people.qq() << endl;
        // }
        // if(people.has_wechat()){
        //     cout << "联系人微信号：" << people.wechat() << endl;
        // }   
        switch (people.other_contact_case()) {
        case contacts2::PeopleInfo::kQq:
            cout << "联系人QQ号：" << people.qq() << endl;
            break;
        case contacts2::PeopleInfo::kWechat:
            cout << "联系人微信号：" << people.wechat() << endl;
            break;
        case contacts2::PeopleInfo::OTHER_CONTACT_NOT_SET:
            cout << "联系人没有设置其他联系方式" << endl;
            break;
        default:
            cout << "未知的其他联系方式类型" << endl;
            break;
        }
        if(people.remark_size() > 0){
            cout << "联系人备注信息：" << endl;
            // 遍历所有备注信息，remark()返回一个map对象
            for(const auto& remark : people.remark()){
                // remark.first是备注类型，remark.second是备注内容
                cout << "  " << remark.first << ": " << remark.second << endl;
            }
        }
    }
}


int main(){
    // 创建protobuf通讯录对象，用于存储从文件读取的数据
    contacts2::Contacts contacts;

    // 尝试打开本地通讯录文件（二进制读模式）
    fstream input("contacts.bin", ios::in | ios::binary);
    
    // 检查文件是否成功打开
    if (!input.is_open()) {  
        cerr << "无法打开文件 contacts.bin!" << endl;
        return -1;
    }
    // 从文件流中解析protobuf数据（反序列化过程）
    else if(!contacts.ParseFromIstream(&input)){
        cerr << "解析文件失败! 可能是文件格式错误或损坏" << endl;
        input.close();  // 出错时关闭文件流
        return -1;
    }
    
    // 关闭输入文件流（数据已读取完毕）
    input.close();
    
    // 调用打印函数，展示所有联系人信息
    PrintContacts(contacts);

    return 0;
}
